

#ifndef InitFunction_h__
#define InitFunction_h__

void Init(void);

#if defined(__CC_ARM)
//ARM CC
typedef void(*InitEntry_T)(void);
#define __INIT_ENTRY_LEVEL(entry, level)  \
    const InitEntry_T __Init_##entry __attribute__((used, section( "InitEntry" # level))) = entry;

#define INIT_ENTRY_FIRST(entry) __INIT_ENTRY_LEVEL(entry, 0)
#define INIT_ENTRY_EARLY(entry) __INIT_ENTRY_LEVEL(entry, 1)
#define INIT_ENTRY_MAIN(entry)	__INIT_ENTRY_LEVEL(entry, 2)
#define INIT_ENTRY_LATER(entry)	__INIT_ENTRY_LEVEL(entry, 3)

#define INIT_FUNC(func)		__INIT_ENTRY_LEVEL(func, 2) 


#elif (defined (__ICCARM__)) 
//IAR
typedef void(*InitEntry_T)(void);

#define __INIT_ENTRY_LEVEL(entry, level)  \
    __root const InitEntry_T __Init_##entry @ "InitEntry" # level  = entry;
    
#define INIT_ENTRY_EARLY(entry) __INIT_ENTRY_LEVEL(entry, 1)
#define INIT_ENTRY_MAIN(entry)	__INIT_ENTRY_LEVEL(entry, 2)
#define INIT_ENTRY_LATER(entry)	__INIT_ENTRY_LEVEL(entry, 3)

#define INIT_FUNC(func)		__INIT_ENTRY_LEVEL(func, 2) 


#else
//VS2015
typedef void(__cdecl *InitEntry_T)(void);

#pragma section(".init$s")

#define INIT_FUNC(func)		\
	__declspec(allocate(".init$s")) \
	const volatile InitEntry_T __Init_##func = func;
#endif //(defined (__ICCARM__)) 
#endif // InitFunction_h__

